package com.shadowtorcher.stdisk.logic;

import com.shadowtorcher.soulknife.SoulKnifeDB;
import com.shadowtorcher.soulknife.exception.BeanConfigErrorException;
import com.shadowtorcher.stdisk.bean.*;
import com.shadowtorcher.stdisk.util.FileUtil;
import com.shadowtorcher.stdisk.util.StaticUtils;

import java.io.IOException;
import java.sql.SQLException;
import java.util.List;

public class FileDeleter {
    public static final int SUB_REFERENCE = 0;
    public static final int MOVE_TO_BIN = 1;
    public static final int REALLY_DELETE = 2;
    public static final int ERROR = -1;
    private LogicFileBean logicFile;
    private UserBean user;

    public FileDeleter(LogicFileBean logicFile, UserBean user) {
        this.user = user;
        this.logicFile = logicFile;
    }

    public static FileDeleter getByUuid(String uuid, UserBean user) throws SQLException {
        try {
            LogicFileBean logicFile = SoulKnifeDB.selectWhere("LogicFileID = ?", uuid).setClass(LogicFileBean.class).get(0);
            return new FileDeleter(logicFile, user);
        } catch (BeanConfigErrorException e) {
            e.printStackTrace();
            return null;
        }
    }

    public long getFileSize() throws SQLException {
        try {
            return SoulKnifeDB.selectWhere("PhysicsFileID = ?", logicFile.getPhysicsFileID()).setClass(PhysicsFileBean.class).get(0).getFileSize();
        } catch (BeanConfigErrorException e) {
            e.printStackTrace();
        }
        return 0;
    }

    public int doDelete() throws SQLException {
        try {
            if (isInBin(logicFile)) {
                SoulKnifeDB.deletWhere("LogicFileID = ?", logicFile.getLogicFileID()).setClass(LogicFileBean.class);
                sharedFileDelete(logicFile);
                PhysicsFileBean physicsFile = SoulKnifeDB.selectWhere("PhysicsFileID = ?", logicFile.getPhysicsFileID()).setClass(PhysicsFileBean.class).get(0);
                user.setUsedSpace(user.getUsedSpace() - getFileSize());
                SoulKnifeDB.updateWhere(user, "UserID = ?", user.getUserID()).setClass(UserBean.class);
                switch (physicsFile.getReferenceCount()) {
                    case 0:
                    case 1:
                        reallyDelete(physicsFile);
                        return REALLY_DELETE;
                    default:
                        subReference(physicsFile);
                        return SUB_REFERENCE;
                }
            } else {
                moveToBin(logicFile);
                return MOVE_TO_BIN;
            }
        } catch (BeanConfigErrorException | IOException e) {
            e.printStackTrace();
            return ERROR;
        }
    }

    private void subReference(PhysicsFileBean physicsFile) throws SQLException, BeanConfigErrorException {
        StaticUtils.subReferenceCount(physicsFile.getPhysicsFileID());
        SoulKnifeDB.deletWhere("LogicFileID = ?", logicFile.getLogicFileID()).setClass(LogicFileBean.class);
    }

    private void moveToBin(LogicFileBean logicFile) throws SQLException, BeanConfigErrorException {
        logicFile.setLogicPath("bin/");
        SoulKnifeDB.updateWhere(logicFile, "LogicFileID = ?", logicFile.getLogicFileID()).setClass(LogicFileBean.class);
    }

    private void reallyDelete(PhysicsFileBean physicsFile) throws SQLException, BeanConfigErrorException, IOException {
        List<CdnBean> list = SoulKnifeDB.selectAll().setClass(CdnBean.class);
        for (CdnBean cdn : list) {
            FileUtil.deleteFile(physicsFile, cdn);
        }
        SoulKnifeDB.deletWhere("PhysicsFileID = ?", physicsFile.getPhysicsFileID()).setClass(PhysicsFileBean.class);

    }

    private void sharedFileDelete(LogicFileBean logicFileBean) throws SQLException, BeanConfigErrorException {
        List<SharedFileBean> list = SoulKnifeDB.selectWhere("LogicFileID = ?", logicFileBean.getLogicFileID()).setClass(SharedFileBean.class);
        for (SharedFileBean sharedFile : list) {
            List<CommentBean> comments = SoulKnifeDB.selectWhere("SharedFileID = ?", sharedFile.getSharedFileID()).setClass(CommentBean.class);
            for (CommentBean comment : comments) {
                SoulKnifeDB.deletWhere("SharedFileID = ?", comment.getSharedFileID()).setClass(CommentBean.class);
                break; // SharedFileID 不同评论对映的 SharedFileID 是相同的
            }
            SoulKnifeDB.deletWhere("SharedFileID = ?", sharedFile.getSharedFileID()).setClass(SharedFileBean.class);
        }
    }

    private boolean isInBin(LogicFileBean logicFile) {
        return logicFile.getLogicPath().startsWith("bin/");
    }
}
